package com.unidt.www.module.bpm.service.task.impl;

import cn.hutool.core.collection.CollUtil;
import com.unidt.www.framework.common.util.object.ConvertUtil;
import com.unidt.www.framework.flowable.core.util.FlowableUtils;
import com.unidt.www.framework.mybatis.core.util.ColumnUtil;
import com.unidt.www.module.bpm.dal.dataobject.definition.ActReActConfigDo;
import com.unidt.www.module.bpm.dal.mysql.definition.ActReActConfigMapper;
import com.unidt.www.module.bpm.dto.ActReActBtnConfigDto;
import com.unidt.www.module.bpm.dto.ActReActTimeConfigDto;
import com.unidt.www.module.bpm.service.task.ActReActConfigService;
import com.unidt.www.module.bpm.vo.ActReActBtnConfigVo;
import com.unidt.www.module.bpm.vo.ActReActDeadTimeConfigVo;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author sk
 * @Description:
 * @Date 2023/2/7 17:10
 **/
@Service
public class ActReActConfigServiceImpl implements ActReActConfigService {

    @Autowired
    ActReActConfigMapper actReActConfigMapper;

    @Resource
    private RepositoryService repositoryService;


    @Resource
    private TaskService taskService;


    @Override
    public ActReActBtnConfigVo getBaseBtnConfig(String modelId, String actId) {
        ActReActConfigDo actReActConfigDo =  actReActConfigMapper.getActBaseConfig(modelId,actId);
        return ConvertUtil.convert(actReActConfigDo,ActReActBtnConfigVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBtnConfig(ActReActBtnConfigDto actReActBtnConfigDto) {

        String modelId = actReActBtnConfigDto.getModelId();
        String actId =   actReActBtnConfigDto.getActId();
        ActReActConfigDo actReActConfigDo = this.actReActConfigMapper.getActBaseConfig(modelId,actId);
        if(Objects.nonNull(actReActConfigDo)){
            /**
             * 存在 则 copy 更新
             */
            ConvertUtil.copyProperties(actReActBtnConfigDto,actReActConfigDo);
            this.actReActConfigMapper.updateById(actReActConfigDo);
        }else {
            /**
             * 不存在则 插入
             */
            actReActConfigDo = ConvertUtil.convert(actReActBtnConfigDto,ActReActConfigDo.class);
            this.actReActConfigMapper.insert(actReActConfigDo);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void renewConfig(String modelId, String processDefinitionId) {

        List<ActReActConfigDo> list =  this.actReActConfigMapper.getLastByModelId(modelId);
        BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);

        /**
         * 删除多余节点
         */

        List<UserTask> userTasks = FlowableUtils.getBpmnModelElements(model, UserTask.class);

        if (CollUtil.isNotEmpty(userTasks)) {
            /**
             * 遍历新的流程节点
             * 如果新的流程节点有减少 则删除
             */
            List<String> actIds = userTasks.stream().map(UserTask::getId).collect(Collectors.toList());

            list.forEach(c->{
                ActReActConfigDo configDo = new ActReActConfigDo();
                BeanUtils.copyProperties(c,configDo, ColumnUtil.getName(ActReActConfigDo::getId));
                String actId = configDo.getActId();

                if(actIds.contains(actId)){
                    configDo.setProcessDefinitionId(processDefinitionId);
                    this.actReActConfigMapper.insert(configDo);
                }else {
                    /**
                     * 删除
                     */
                    actReActConfigMapper.deleteConfig(c.getId());
                }

            });

        }

    }

    @Override
    public ActReActDeadTimeConfigVo getBaseTimeConfig(String modelId, String actId) {
        ActReActConfigDo actReActConfigDo =  actReActConfigMapper.getActBaseConfig(modelId,actId);
        return ConvertUtil.convert(actReActConfigDo,ActReActDeadTimeConfigVo.class);
    }

    @Override
    public void saveTimeConfig(ActReActTimeConfigDto actReActTimeConfigDto) {

        String modelId = actReActTimeConfigDto.getModelId();
        String actId =   actReActTimeConfigDto.getActId();
        ActReActConfigDo actReActConfigDo = this.actReActConfigMapper.getActBaseConfig(modelId,actId);
        if(Objects.nonNull(actReActConfigDo)){
            /**
             * 存在 则 copy 更新
             */
            ConvertUtil.copyProperties(actReActTimeConfigDto,actReActConfigDo);
            this.actReActConfigMapper.updateById(actReActConfigDo);
        }else {
            /**
             * 不存在则 插入
             */
            actReActConfigDo = ConvertUtil.convert(actReActTimeConfigDto,ActReActConfigDo.class);
            this.actReActConfigMapper.insert(actReActConfigDo);
        }
    }

    @Override
    public Boolean saveBatchBtnConfig(List<ActReActBtnConfigDto> actReActBtnConfigDtos) {
        if(actReActBtnConfigDtos!=null && !actReActBtnConfigDtos.isEmpty()){

            actReActBtnConfigDtos.forEach(a->{
                this.saveBtnConfig(a);
            });

        }
        return  true;
    }

    @Override
    public Boolean saveBatchTimeConfig(List<ActReActTimeConfigDto> actReActTimeConfigDtoList) {
        if(actReActTimeConfigDtoList!=null && !actReActTimeConfigDtoList.isEmpty()){

            actReActTimeConfigDtoList.forEach(a->{
                this.saveTimeConfig(a);
            });

        }
        return  true;
    }

    @Override
    public ActReActBtnConfigVo getProcessConfig(String processDefinitionId, String actId) {
        ActReActConfigDo actReActConfigDo =  actReActConfigMapper.getProcessConfig(processDefinitionId,actId);
        return ConvertUtil.convert(actReActConfigDo,ActReActBtnConfigVo.class);

    }

    @Override
    public ActReActDeadTimeConfigVo getProcessTimeConfig(String processDefinitionId, String actId) {
        ActReActConfigDo actReActConfigDo =  actReActConfigMapper.getProcessConfig(processDefinitionId,actId);
        return ConvertUtil.convert(actReActConfigDo,ActReActDeadTimeConfigVo.class);    }

    @Override
    public ActReActBtnConfigVo getTaskProcessConfig(String taskId) {
        Task task  =taskService.createTaskQuery().taskId(taskId).singleResult();
        if(task!=null){
             String processDefinitionId =  task.getProcessDefinitionId();
             String actId =  task.getTaskDefinitionKey();
             ActReActConfigDo actReActConfigDo =  actReActConfigMapper.getProcessConfig(processDefinitionId,actId);
            return ConvertUtil.convert(actReActConfigDo,ActReActBtnConfigVo.class);

        }
        return new ActReActBtnConfigVo();
    }
}
